﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DevExpress.Xpf.Grid;
using Modularity.EODServices;
using OpenLS.Core;
using OpenLS.Spreadsheet;
using OpenLS.Spreadsheet.Formats;
using OpenLS.Spreadsheet.UI.Interfaces;
using QuantumWorkspace.SessionManager;
using EODQuery = Modularity.DataModules.EODDataModule.EODQuery;

namespace Modularity
{
    public class EODDataModule : IDataModule
    {
        private EODServices.EODServicesClient aEodServicesClient;
        
        public EODDataModule()
        {
            _AllQueries = new List<EODQuery>();
            aEodServicesClient = new EODServicesClient();
        }

        private string _menuText;
        private Workbook _currentWorkbook;
        private GridControl _currentGridControl;
        private JsonDataTableFormat _JsonTableStructure;

        private string strMarketColumn = "MARKET";
        private int _MarketColumnIndex = -1;

        private string strBeginDateColumn = "BEGIN";
        private int _BeginDateColumnIndex = -1;


        private string strEndDateColumn = "END";
        private int _EndDateColumnIndex = -1;


        private string strTickerColumn = "TICKER";
        private int _TickerColumnIndex = -1;

        private List<EODQuery> _AllQueries;


        /// <summary>
        /// Reduces all queries found in the current query definition
        /// </summary>
        private void ReduceQueries()
        {

        }

        private List<EODServices.EODQuery> MappedQueries()
        {
            List<EODServices.EODQuery> _mappedQueries = new List<EODServices.EODQuery>();
            foreach (var aQuery in _AllQueries)
            {
                EODServices.EODQuery webServiceQuery = new EODServices.EODQuery();
                webServiceQuery.Market = aQuery.Market;
                webServiceQuery.FullMarketQuery = aQuery.FullMarketQuery;
                webServiceQuery.FullTimeLine = aQuery.FullTimeLine;
                if (aQuery.Tickers == null)
                {
                    webServiceQuery.Tickers = new string[0];
                }
                else
                {
                    webServiceQuery.Tickers = aQuery.Tickers.ToArray();
                }

                webServiceQuery.TimeIntervals = new EODServices.EODQuery.TimeInterval[aQuery.TimeIntervals.Count];
                int counter = 0;
                foreach (var aQueryTimeInterval in aQuery.TimeIntervals)
                {
                    webServiceQuery.TimeIntervals[counter] = new EODServices.EODQuery.TimeInterval();
                    if (aQueryTimeInterval.begin.HasValue)
                        webServiceQuery.TimeIntervals[counter].begin = aQueryTimeInterval.begin.Value;
                    if (aQueryTimeInterval.end.HasValue)
                        webServiceQuery.TimeIntervals[counter].begin = aQueryTimeInterval.end.Value;
                    counter++;
                }
                _mappedQueries.Add(webServiceQuery);
            }
            return _mappedQueries;
        }

        public string MenuText
        {
            get { return _menuText; }
        }

        public Workbook CurrentWorkbook
        {
            get { return _currentWorkbook; }
            set { _currentWorkbook = value; }
        }

        public GridControl CurrentGridControl
        {
            get { return _currentGridControl; }
            set { _currentGridControl = value; }
        }

        private object getRowColumn(object itemRow, string strMarket)
        {
            object CellValue = null;
            switch (strMarket)
            {
                case "MARKET":
                    if (_MarketColumnIndex == -1)
                        CellValue = null;
                    else
                        CellValue = itemRow.GetType().GetProperty("Col" + _MarketColumnIndex).GetValue(itemRow);
                    break;
                case "BEGIN":
                    if (_BeginDateColumnIndex == -1)
                        CellValue = null;
                    else
                        CellValue = itemRow.GetType().GetProperty("Col" + _BeginDateColumnIndex).GetValue(itemRow);
                    break;
                case "END":
                    if (_EndDateColumnIndex == -1)
                        CellValue = null;
                    else
                        CellValue = itemRow.GetType().GetProperty("Col" + _EndDateColumnIndex).GetValue(itemRow);
                    break;
                case "TICKER":
                    if (_TickerColumnIndex == -1)
                        CellValue = null;
                    else
                        CellValue = itemRow.GetType().GetProperty("Col" + _TickerColumnIndex).GetValue(itemRow);
                    break;
            }
            return CellValue;
        }

        private void MapQueries(List<object> rows)
        {
            List<string> FullMarketQueries_MarketNames = new List<string>();
            int rowIndexer = 0;
            foreach (var aRow in rows)
            {
                var ticker = getRowColumn(aRow, "TICKER");
                EODQuery aMarketQuery = new EODQuery();
                aMarketQuery.OriginalQueryRowIndexes.Add(rowIndexer);
                if (getRowColumn(aRow, "MARKET") != null)
                    aMarketQuery.Market = getRowColumn(aRow, "MARKET").ToString();
                var beginDate = getRowColumn(aRow, "BEGIN");
                var endDate = getRowColumn(aRow, "END");
                if (!((beginDate == null) && (endDate == null)))
                {
                    EODQuery.TimeInterval aTimeInterval = new EODQuery.TimeInterval();
                    if (beginDate != null)
                    {
                        if (beginDate is DateTime)
                            aTimeInterval.begin = DateTime.Parse(beginDate.ToString());
                    }  
                    else
                    {
                        aTimeInterval.begin = null;
                    }

                    if (endDate != null)
                    {
                        if (endDate is DateTime)
                            aTimeInterval.end = DateTime.Parse(endDate.ToString());
                    }
                    else
                    {
                        aTimeInterval.end = null;
                    }
                    aMarketQuery.TimeIntervals.Add(aTimeInterval);
                }

                if (ticker == null)
                {
                    aMarketQuery.FullMarketQuery = true;
                    if (_MarketColumnIndex != -1)
                        _AllQueries.Add(aMarketQuery);
                }
                else
                {
                    aMarketQuery.FullMarketQuery = false;
                    aMarketQuery.Tickers = new List<string>();
                    aMarketQuery.Tickers.Add(ticker.ToString());
                    _AllQueries.Add(aMarketQuery);
                }
                
                rowIndexer++;
            }
        }

  
     

        public void DefineTableJsonFormat(JsonDataTableFormat structure)
        {
            _JsonTableStructure = structure;
            var collection = CodeSession.Instance.GetDataGridRowsExternal(structure);
            Dictionary<string, string> columnNames = CodeSession.Instance.GetDataGridColumnsNames();

            int _colIndex = 0;
            foreach (var columnKeyValuePar in columnNames)
            {
                switch (columnKeyValuePar.Value)
                {
                    case "MARKET":
                        _MarketColumnIndex = _colIndex;
                        break;
                    case "BEGIN":
                        _BeginDateColumnIndex = _colIndex;
                        break;
                    case "END":
                        _EndDateColumnIndex = _colIndex;
                        break;
                    case "TICKER":
                        _TickerColumnIndex = _colIndex;
                        break;
                }
                _colIndex++;
            }
            MapQueries(collection.ToList());
            ReduceQueries();

            var mappedQueries = MappedQueries().ToArray();

            var results = aEodServicesClient.ComputeQueries(mappedQueries);

            // FORCE REFRESH
            CurrentGridControl.ItemsSource = results;

        }

        public void CopyToSpreadsheet()
        {
            var activeSheet = this.CurrentWorkbook.GetActiveWorksheet();
            if (activeSheet != null)
            {
                var range = activeSheet.ActiveCell;
                int activeCellRowIndex = range.Row.Index;
                int activeCellColumnIndex = range.Column.Index;

                // this.CurrentGridControl.
                var viewsItems = (IEnumerable)this.CurrentGridControl.ItemsSource;

                // var viewsItems = this.CurrentGridControl.View.RootRowsContainer.Items;
                int nbColumns = this.CurrentGridControl.Columns.Count;
                for (int columnIndex = 0; columnIndex < nbColumns; columnIndex++)
                {
                    string strColumnName = ((DevExpress.Xpf.Grid.ColumnBase)(this.CurrentGridControl.Columns[columnIndex])).FieldName;
                    activeSheet[activeCellRowIndex, activeCellColumnIndex + columnIndex].Value = strColumnName;
                }
                int rowCounter = 1;
                foreach (var rowDataBase in viewsItems)
                {
                    // var itemRow = ((DevExpress.Xpf.Grid.RowData)(rowDataBase)).Row;
                    for (int columnIndex = 0; columnIndex < nbColumns; columnIndex++)
                    {
                        string strColumnName = ((DevExpress.Xpf.Grid.ColumnBase)(this.CurrentGridControl.Columns[columnIndex])).FieldName;
                        var cellValue = rowDataBase.GetType().GetProperty(strColumnName).GetValue(rowDataBase);
                                                        // itemRow.GetType().GetProperty(strColumnName).GetValue(itemRow);

                        if (cellValue is DateTime)
                        {
                            CellFormatter.ApplyDateFormat(activeSheet[activeCellRowIndex + rowCounter, activeCellColumnIndex + columnIndex], cellValue);
                            activeSheet[activeCellRowIndex + rowCounter, activeCellColumnIndex + columnIndex].Value = cellValue;
                        }
                        else if (cellValue is double)
                        {
                            CellFormatter.TrySetDouble(
                                activeSheet[activeCellRowIndex + rowCounter, activeCellColumnIndex + columnIndex],
                                cellValue.ToString());
                        }
                        else
                        {
                            activeSheet[activeCellRowIndex + rowCounter, activeCellColumnIndex + columnIndex].Value = cellValue;
                        }
                    }
                    rowCounter++;
                    if (rowCounter > 5000)
                        break;
                }

            }
        }
    }
}
